package cn.neusoft.service.impl;

import cn.neusoft.domain.CargoDeployBill;
import cn.neusoft.domain.DeployBillStageEnum;
import cn.neusoft.domain.Warehouse;
import cn.neusoft.mapper.DeployBillMapper;
import cn.neusoft.mapper.WarehouseMapper;
import cn.neusoft.service.DepBillService;
import cn.neusoft.service.DispatchService;
import cn.neusoft.service.WarehouseAdministrateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class DepBillImp implements DepBillService {

    @Autowired
    private DeployBillMapper deployBillMapper;
    @Autowired
    private WarehouseMapper warehouseMapper;
    @Autowired
    private DispatchService dispatchService;

    @Override
    public List<CargoDeployBill> searchDepBill(int warehouseID) {
        List<CargoDeployBill> list = null;

        list = deployBillMapper.findByAimWarehouseID(warehouseID);

        return list;
    }




    @Override
    public int deleteDepBill(int billID) {
        int ans = 0;

        ans = deployBillMapper.deleteByID(billID);

        return ans;
    }

    @Override
    public CargoDeployBill getDepBillByID(int id) {
        return deployBillMapper.findByID(id);
    }

    @Override
    public int revertDepBill(CargoDeployBill cargoDeployBill) {
        int ans = 0;

        if(cargoDeployBill != null){
            Warehouse warehouse = warehouseMapper.findByName(cargoDeployBill.getAimWarehouseName());
            if(warehouse != null){
                Map<String, Double> preMap = warehouse.getPreCargos();
                Map<String, Double> preOutMap = warehouse.getPreOutCargos();
                boolean isPass = true;
                switch (cargoDeployBill.getStage()){
                    case PRE_IN:
                        isPass = true;
                        for(Map.Entry<String, Double> entry : cargoDeployBill.getPlanCargosInf().entrySet()){
                            Double pre = preMap.get(entry.getKey());
                            if(pre != null && pre >= entry.getValue()){
                                continue;
                            }
                            isPass = false;
                        }
                        if(isPass){
                            for(Map.Entry<String, Double> entry : cargoDeployBill.getPlanCargosInf().entrySet()){
                                preMap.put(entry.getKey(), preMap.get(entry.getKey()) - entry.getValue());
                            }
                            ans = warehouseMapper.update(warehouse);
                        }
                        else{
                            ans = -1;
                        }
                        break;
                    case PRE_OUT:
                        isPass = true;
                        for(Map.Entry<String, Double> entry : cargoDeployBill.getPlanCargosInf().entrySet()){
                            Double preOut = preOutMap.get(entry.getKey());
                            if(preOut != null && preOut >= entry.getValue()){
                                continue;
                            }
                            isPass = false;
                        }
                        if(isPass){
                            for(Map.Entry<String, Double> entry : cargoDeployBill.getPlanCargosInf().entrySet()){
                                preOutMap.put(entry.getKey(), preOutMap.get(entry.getKey()) - entry.getValue());
                            }
                            ans = warehouseMapper.update(warehouse);
                        }
                        else{
                            ans = -1;
                        }
                        break;
                    default:
                        ans = 1;
                        break;
                }
            }

        }

        return ans;
    }

    @Override
    public int generateDepBill(CargoDeployBill cargoDeployBill) {
        int ans = 0;

        if(cargoDeployBill != null){
            boolean isPer = this.isPermittedCreate(cargoDeployBill);
            if(isPer){
                ans = deployBillMapper.insert(cargoDeployBill);
                    if(ans > 0){
//                      System.out.println(cargoDeployBill.getId());
                        ans = dispatchService.applyDepBill(cargoDeployBill.getId());
                    }
            }

        }

        return ans;
    }

    @Override
    public int stageChangeDepBill(CargoDeployBill cargoDeployBill, DeployBillStageEnum stageEnum) {
        int ans = 0;

        if(cargoDeployBill != null){
            switch(cargoDeployBill.getStage()){
                case PRE_IN:
                    if(stageEnum == DeployBillStageEnum.HAD_IN){
                        cargoDeployBill.setStage(DeployBillStageEnum.HAD_IN);
                        ans = deployBillMapper.updateBill(cargoDeployBill);
                        if(ans > 0){
                            ans = dispatchService.applyDepBill(cargoDeployBill.getId());
                        }
                    }
                    break;
                case PRE_OUT:
                    if(stageEnum == DeployBillStageEnum.HAD_OUT){
                        cargoDeployBill.setStage(DeployBillStageEnum.HAD_OUT);

                    }
                    else if(stageEnum == DeployBillStageEnum.RECEIVED){
                        cargoDeployBill.setStage(DeployBillStageEnum.RECEIVED);
                    }
                    else{
                        break;
                    }
                    ans = deployBillMapper.updateBill(cargoDeployBill);
                    if(ans > 0){
                        ans = dispatchService.applyDepBill(cargoDeployBill.getId());
                    }
                    break;
                default:
                    break;
            }
        }

        return ans;
    }

    @Override
    public boolean isPermittedCreate(CargoDeployBill cargoDeployBill) {
        boolean ans = false;
        if(cargoDeployBill != null){
            Warehouse warehouse = warehouseMapper.findByName(cargoDeployBill.getAimWarehouseName());
            if(warehouse != null){
                Map<String, Double> maxMap = warehouse.getCargoMaxLevel();
                Map<String, Double> preMap = warehouse.getPreCargos();
                Map<String, Double> quanMap = warehouse.getCargos();
                Map<String, Double> preOutMap = warehouse.getPreOutCargos();
                if(cargoDeployBill.getStage() == DeployBillStageEnum.PRE_IN){
                    boolean isPass = true;
                    for(Map.Entry<String, Double> entry : cargoDeployBill.getPlanCargosInf().entrySet()){
                        Double max = maxMap.get(entry.getKey());
                        Double pre = preMap.get(entry.getKey());
                        Double quan = quanMap.get(entry.getKey());
                        if(max == null || pre == null || quan == null){
                            isPass = false;
                            break;
                        }
                        if(entry.getValue() >=0){
                            max = max - pre - quan;
                            if(entry.getValue() <= max){
                                continue;
                            }

                        }
                        isPass = false;
                        break;
                    }
                    ans = isPass;
                }
                else if(cargoDeployBill.getStage() == DeployBillStageEnum.PRE_OUT){
                    boolean isPass = true;
                    for(Map.Entry<String, Double> entry : cargoDeployBill.getPlanCargosInf().entrySet()){
                        Double quan = quanMap.get(entry.getKey());
                        Double preOut = preOutMap.get(entry.getKey());
                        if(quan == null || preOut == null){
                            isPass = false;
                            break;
                        }
                        if(entry.getValue() >= 0){
                            if(quan - preOut - entry.getValue() >= 0){
                                continue;
                            }
                        }
                        isPass = false;
                        break;
                    }
                    ans = isPass;
                }
            }
            else{
                ans = false;
            }
        }
        return ans;
    }

    @Override
    public int changeDepBill(CargoDeployBill cargoDeployBill) {
        int ans = 0;

        if(cargoDeployBill != null){
            ans = deployBillMapper.updateBill(cargoDeployBill);
        }

        return ans;
    }
    @Override
    public List<CargoDeployBill> queryDepBill(DeployBillStageEnum stage, Date from, Date to) {
        List<CargoDeployBill> list = new ArrayList<CargoDeployBill>();

      List<CargoDeployBill> temp = deployBillMapper.getAll();
      for(CargoDeployBill bill : temp){
        if(stage == DeployBillStageEnum.ALL || bill.getStage() == stage){
            if(from != null&& bill.getDate().compareTo(from) < 0)
                continue;
            if(to != null && bill.getDate().compareTo(to) > 0)
                continue;
            list.add(bill);
        }
      }


        return list;
    }
}
